<template>
  <lay-container fluid="true" class="role-box">
    <lay-card>
      <lay-form style="margin-top: 10px">
        <lay-row>
          <lay-col :md="5">
            <lay-form-item>
              <lay-input v-model="searchQueryPage.roleName" 
                placeholder="角色名称" size="sm" :allow-clear="true"></lay-input>
            </lay-form-item>
          </lay-col>
          <lay-col :md="5">
            <lay-form-item label=" " label-width="10">
              <lay-input v-model="searchQueryPage.roleCode" 
                placeholder="角色标识" size="sm" :allow-clear="true" ></lay-input>
            </lay-form-item>
          </lay-col>
          <lay-col :md="5">
            <lay-form-item>
              <lay-button style="margin-left: 20px" type="normal" size="sm" @click="toSearch">
                查询
              </lay-button>
              <lay-button size="sm" @click="toReset"> 重置 </lay-button>
            </lay-form-item>
          </lay-col>
        </lay-row>
      </lay-form>
    </lay-card>
    <!-- table -->
    <div class="table-box">
      <lay-table id="roleId" :page="searchQueryPage" :height="'100%'" :columns="columns" :loading="loading" :default-toolbar="true"
        :data-source="dataSource" v-model:selected-keys="selectedKeys" @sortChange="sortChange"  @change="toSearch">
        <template v-slot:toolbar>
          <lay-button size="sm" type="primary" @click="changeVisibleRole('新增', null)"> <lay-icon class="layui-icon-addition"></lay-icon> 新增</lay-button>
          <lay-button size="sm" @click="toRemove"> <lay-icon class="layui-icon-delete"></lay-icon>  </lay-button>
        </template>
        <template #status="{ row }">
          <lay-switch :model-value="row.status == 1" @change="changeStatus($event, row)"></lay-switch>
        </template>
        <template v-slot:operator="{ row }">
          <lay-button size="xs" border="green" border-style="dashed" @click="changeVisibleRole('编辑', row)">编辑</lay-button>
          <lay-button size="xs" border="blue" border-style="dashed" @click="toPrivileges(row)">分配权限</lay-button>
          <lay-popconfirm content="确定要删除此角色吗?" @confirm="toOneRemove(row.roleId)" @cancel="cancel">
            <lay-button size="xs" border="red" border-style="dashed">删除</lay-button>
          </lay-popconfirm>
        </template>
      </lay-table>
    </div>

    <lay-layer v-model="visibleRole" :title="title" :area="['700px', '200px']">
      <div style="padding: 20px">
        <lay-form :model="formData" ref="formRef" required>
          <lay-col md="12">
            <lay-form-item label="角色名称" prop="roleName">
              <lay-input v-model="formData.roleName"></lay-input>
            </lay-form-item>
            <lay-form-item label="角色标识" prop="roleCode">
              <lay-input v-model="formData.roleCode"></lay-input>
            </lay-form-item>
          </lay-col>
          <lay-col md="12">
            <lay-form-item label="排序" prop="sort">
              <lay-input-number v-model="formData.sort" style="width: 100%" position="right"></lay-input-number>
            </lay-form-item>
          </lay-col>
        </lay-form>
        <div style="width: 100%; text-align: center">
          <lay-button size="sm" type="primary" @click="toSubmit">保存</lay-button>
          <lay-button size="sm" @click="toCancel">取消</lay-button>
        </div>
      </div>
    </lay-layer>

    <lay-layer v-model="visibleMenu" title="分配权限" :area="['500px', '450px']">
      <div style="height: 320px; overflow: auto">
        <lay-tree style="margin-left: 40px; margin-top: 18px;" :tail-node-icon="false" v-model:checkedKeys="checkedMenuKeys"
          :data="menuDataSource" :showCheckbox="showMenuCheckbox" :replaceFields="replaceMenuFields">
          <template #title="{ data }">
            <lay-icon :class="data.icon"></lay-icon>
            {{ data.menuName }}
          </template>
        </lay-tree>
      </div>
      <lay-line></lay-line>
      <div style="width: 90%; text-align: right">
        <lay-button size="sm" type="primary" @click="toSubmitRoleMenu">保存</lay-button>
        <lay-button size="sm" @click="toCancel">取消</lay-button>
      </div>
    </lay-layer>
  </lay-container>
</template>

<script setup lang="ts">
  import { ref, reactive } from 'vue';
  import { layer } from '@layui/layui-vue';
  
  import { roleList, roleAdd, roleRemove, menuTree, roleMenuList, roleMenuAdd } from '../../../api/module/system';
  
  // 其他
  // -- 加载中
  const loading = ref(false);
  const title = ref('新增');
  // 角色
  // -- 是否可见
  const visibleRole = ref(false);
  // -- 查询
  const searchQueryPage = ref({ roleName: '', roleCode: '', page: 1, size: 10, total: 0, orderProperty: '', orderSort: 0 });
  // -- 选中的
  const selectedKeys = ref();
  // -- 数据源
  const dataSource = ref([]);
  // -- 表结构
  const columns = ref([
    { title: '选项', type: 'checkbox' },
    { title: '编号', key: 'roleId', sort: 'desc' },
    { title: '角色名称', key: 'roleName', sort: 'desc' },
    { title: '角色标识', key: 'roleCode', sort: 'desc' },
    { title: '启用', width: '80px', key: 'status', customSlot: 'status' },
    { title: '操作', width: '180px', customSlot: 'operator', key: 'operator', fixed: 'right' }
  ]);
  // --
  var checkRoleId = 0;
  // 菜单
  // -- 是否可见
  const visibleMenu = ref(false);
  // -- 选中的
  const checkedMenuKeys = ref([]);
  // -- 显示选项
  const showMenuCheckbox = ref(true);
  // -- 数据源
  const menuDataSource = ref([]);
  // -- 树节点结构
  const replaceMenuFields = ref({ id: 'menuId', title: 'menuName', children: 'children' });
  // 表单
  // -- 表单数据
  const formData = ref({ roleName: '', roleCode: '', sort: 99, status: 1 });
  // -- 表单标签
  const formRef = ref();
  
  // -- 方法函数
  // 加载默认数据
  function loadDataSource(){
    roleList(searchQueryPage.value).then(({ data, code, msg }) => {
      if (code == 200) {
        searchQueryPage.value.total = data.total;
        dataSource.value = data.list;
      }
      loading.value = false;
    })
  }
  // 加载菜单数据
  function loadMenuDataSource(){
    menuTree({}).then(({ data, code }) => {
      if (code == 200) {
        menuDataSource.value = data;
      }
      loading.value = false;
    })
  }
  // 刷新
  function toReset(){
    searchQueryPage.value.roleName = '';
    searchQueryPage.value.roleCode = '';
  }
  // 搜索
  function toSearch(){
    searchQueryPage.value.page = 1
    loadDataSource()
  }
  // 搜索 sort
  function sortChange(key : any, sort : number){
    searchQueryPage.value.orderProperty = key;
    searchQueryPage.value.orderSort = sort;
  }
  // 删除
  function toOneRemove(roleId: number){
    selectedKeys.value = [roleId];
    toRemove();
  }
  function toRemove(){
    if (selectedKeys.value.length == 0) {
      layer.msg('您未选择数据，请先选择要删除的数据', { icon: 3, time: 2000 })
      return
    }
    layer.confirm('您将删除所有选中的数据？', {
      title: '提示',
      btn: [
        {
          text: '确定',
          callback: (id : any) => {
            roleRemove({ids: selectedKeys.value}).then(({ code, msg }) => {
              if (code == 200) {
                layer.msg('成功删除！', { icon: 1, time: 1000 });
              } else {
                layer.msg(msg, { icon: 2, time: 1000 })
              }
              toSearch();
            })
            layer.close(id)
          }
        },
        {text: '取消', callback: (id : any) => { layer.msg('您已取消操作');layer.close(id); }}
      ]
    })
  }
  // 提交
  function toSubmit(){
    roleAdd(formData.value).then(({ code, msg, message }) => {
      if (code == 200) {
        layer.msg('保存成功！', { icon: 1, time: 1000 });
      } else {
        layer.msg(message? message:msg, { icon: 2, time: 1000 })
      }
      toSearch();
      visibleRole.value = false
    });
  }
  function toSubmitRoleMenu(){
    var layerId = layer.msg("处理中", { icon : 16, time: 3000})
    roleMenuAdd({"roleId": checkRoleId, "menus": checkedMenuKeys.value}).then(({ code, msg, message }) => {
      if (code == 200) {
        layer.msg('操作成功！', { icon: 1, time: 1000 });
      } else {
        layer.msg(message? message:msg, { icon: 2, time: 1000 })
      }
      layer.close(layerId);
      visibleMenu.value = false
    });
  }
  // 
  function changeStatus(isChecked : boolean, row : any){
    row.status = isChecked? 1 : 0;
    formData.value = row;
    roleAdd(row).then(({code}) => {if(code == 200){layer.msg('修改成功');loadDataSource();}});
  }
  // 
  function changeVisibleRole(text : any, row : any){
    title.value = text
    if (row != null) {
      let info = JSON.parse(JSON.stringify(row))
      formData.value = info
    } else {
      formData.value = { roleName: '', roleCode: '', sort: 99, status: 1  }
    }
    visibleRole.value = !visibleRole.value
  }
  // 
  function toCancel(){
    visibleRole.value = false
    visibleMenu.value = false
  }
  function cancel(){
    layer.msg('您已取消操作')
  }
  function toPrivileges(row : any){
    checkRoleId = row.roleId;
    visibleMenu.value = true;
    roleMenuList({roleId: row.roleId}).then(({ data,code, msg, message }) => {
      if(code == 200){
        var ckIds:never[] = [];
        for (var ij = 0; ij < data.length; ij++) {
          ckIds.push(data[ij].menuId as never);
        }
        checkedMenuKeys.value = ckIds;
      }
    });
  }
  
  // --预执行
  loadMenuDataSource();
  loadDataSource();

</script>

<style scoped>
  .role-box { 
    height: calc(100vh - 110px); 
    margin-top: 10px; box-sizing: border-box;
  } 
  
  .top-search { margin-top: 10px; padding: 10px; height: 40px; border-radius: 4px; background-color: #fff; } 
  
  .table-box { margin-top: 10px; padding: 10px; height: 730px; width: 100%; border-radius: 4px; box-sizing: border-box; background-color: #fff; } 
  
  .search-input { display: inline-block; width: 98%; margin-right: 10px; }
  
  .isChecked { display: inline-block; background-color: #e8f1ff; color: red; }
</style>